import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
  Input,
  Button,
  Field,
  Form,
  Upload,
  Message,
  Switch,
  Checkbox,
  Card,
  Select,
} from '@teamix/ui';
import { YunxiaoIcon } from '@alife/devops-ui';
import AccessSelect from 'components/accessSelect/setting';
import FormItemSwitch from 'atComponents/FormItemSwitch';
import TagForFeature from 'components/tagForFeature';
import { defaultPictureSize } from 'utils/constants.js';
import debounce from 'lodash.debounce';
import { checkProjectName } from 'api/index.js';
import './index.scss';
import CloneTooltip from './cloneTooltip';
import intl from '../../../../../../../../../../locale';
import { getFeature } from 'utils/features';
import { getPathWithRootPath } from 'utils/router';

const { pathResource } = window.FORCE;
const FormItem = Form.Item;
const formItemLayout = {
  labelCol: {
    span: 6,
  },

  wrapperCol: {
    span: 14,
  },
};
const roleInfo = getFeature('setting.download_control.allow_role').project;
const cloneWay = [
  {
    label: 'SSH Clone',
    value: 'ssh-clone',
  },

  {
    label: 'HTTPS Clone',
    value: 'http-clone',
  },

  {
    label: intl.get({
      id: 'code-assets.containers.baseForm.DownloadZipTar',
      defaultMessage: '下载ZIP/TAR',
    }),
    value: 'download',
  },
];

export default class BaseForm extends Component {
  static propTypes = {
    saveGeneral: PropTypes.func,
    searchBranches: PropTypes.func,
    name: PropTypes.string,
    path: PropTypes.string,
    id: PropTypes.number,
    description: PropTypes.string,
    defaultBranch: PropTypes.string,
    visibilityLevel: PropTypes.number,
    tagList: PropTypes.array,
    avatarUrl: PropTypes.string,
    namespaceVisibilityLevel: PropTypes.number,
    isReview: PropTypes.bool,
    checkemail: PropTypes.bool,
    exceptBranch: PropTypes.string,
    isForked: PropTypes.bool,
    sourceProjectVisibilityLevel: PropTypes.number,
    clone_download_info: PropTypes.object,
  };

  static defaultProps = {
    saveGeneral: () => { },
    searchBranches: () => { },
    name: null,
    path: null,
    id: 0,
    description: null,
    defaultBranch: null,
    visibilityLevel: 0,
    namespaceVisibilityLevel: 0,
    tagList: [],
    avatarUrl: null,
    isReview: false,
    checkemail: false,
    exceptBranch: null,
    isForked: false,
    sourceProjectVisibilityLevel: null,
    clone_download_info: null,
  };

  constructor(props) {
    super(props);
    this.field = new Field(this);
    const { avatarUrl } = props;
    const fileList = [];
    if (avatarUrl) {
      fileList.push({
        uid: '0',
        name: this.getAvatarName(avatarUrl),
        state: 'done',
        size: defaultPictureSize,
        downloadUrl: avatarUrl,
        url: avatarUrl,
        imgUrl: avatarUrl,
      });
    }
    this.state = {
      submitting: false,
      fileList,
      method_list: '',
    };

    this.checkName = debounce(this.checkName, 500);
  }

  checkName(value, callback) {
    checkProjectName({ name: value, namespace_id: pathResource.parentId })
      .then(() => {
        callback();
      })
      .catch(() => {
        callback(
          intl.get({
            id: 'code-assets.containers.baseForm.TheCodeLibraryNameAlready',
            defaultMessage: '代码库名称已存在，请重新输入',
          }),
        );
      });
  }

  UNSAFE_componentWillReceiveProps(nextProps) {
    const { clone_download_info: next_clone_download_info } = nextProps;
    const { clone_download_info } = this.props;
    if (next_clone_download_info && next_clone_download_info !== clone_download_info) {
      const defaultRoleList = [];
      const defaultMethodList = [];
      const next_role_list = next_clone_download_info.project_clone_download_role_list || [];
      const next_method_list = next_clone_download_info.project_clone_download_method_list || [];
      next_role_list.forEach((item) => {
        if (item.allowed) {
          defaultRoleList.push(item.role_code);
        }
      });
      next_method_list.forEach((item) => {
        if (item.allowed) {
          defaultMethodList.push(item.permission_code);
        }
      });

      this.field.setValues({
        open_clone_download_control: next_clone_download_info.open_clone_download_control,
        role_list: defaultRoleList,
        method_list: defaultMethodList,
      });
    }
  }

  deleteCloneDownloadKey = (formData) => {
    const { clone_download_info } = this.props;
    try {
      const isControlSame =
        formData.open_clone_download_control === clone_download_info.open_clone_download_control;
      let changedListLength = 0;
      const form_method_list = formData.project_clone_download_method_list;
      const form_role_list = formData.project_clone_download_role_list;
      const default_method_list = clone_download_info.project_clone_download_method_list;
      const default_role_list = clone_download_info.project_clone_download_role_list;

      form_method_list.forEach((item1) => {
        default_method_list.forEach((item2) => {
          if (item2.permission_code === item1.permission_code && item2.allowed !== item1.allowed) {
            changedListLength += 1;
          }
        });
      });
      form_role_list.forEach((item1) => {
        default_role_list.forEach((item2) => {
          if (item2.role_code === item1.role_code && item2.allowed !== item1.allowed) {
            changedListLength += 1;
          }
        });
      });

      if (isControlSame && !changedListLength) {
        delete formData.open_clone_download_control;
        delete formData.project_clone_download_method_list;
        delete formData.project_clone_download_role_list;
      }
    } catch (e) {
      console.error(e);
    }
  };

  handleChangeAccess = (value) => {
    this.field.setValue('visibility_level', value);
  };

  nameValidator = (rule, value, callback) => {
    const { name } = this.props;
    if (!value || value === name) {
      callback();
      return;
    }
    if (value.length > 100) {
      callback(
        intl.get({
          id: 'code-assets.containers.baseForm.TheLengthCannotExceed',
          defaultMessage: '长度不能超过100',
        }),
      );
      return;
    }
    if (/^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,}$/.test(value)) {
      this.checkName(value, callback);
    } else {
      callback(
        intl.get({
          id: 'code-assets.containers.baseForm.ItCanOnlyContainLowercase',
          defaultMessage: "只能包含小写字母和数字、 '_'、'.'和'-'，且只能以小写字母、数字或'_'开头",
        }),
      );
    }
  };

  visibilityLevelCanBeEdited() {
    const { role = '' } = pathResource;
    return ['ORG_ADMIN', 'ORG_OWNER', 'ADMIN', 'MASTER', 'OWNER'].indexOf(role) > -1;
  }

  saveChanges = () => {
    if (this.state.submitting || this.state.method_list) return;
    this.setState({ submitting: true });
    this.field.validate((errors) => {
      if (!errors && !this.state.method_list) {
        const formData = this.field.getValues();
        const { project_clone_download_role_list, project_clone_download_method_list } =
          this.props.clone_download_info || {};

        if (formData.open_clone_download_control) {
          if (formData.role_list) {
            formData.project_clone_download_role_list = project_clone_download_role_list.map(
              (item) => {
                return {
                  role_code: item.role_code,
                  allowed: formData.role_list.includes(item.role_code),
                };
              },
            );
          }

          if (formData.method_list) {
            formData.project_clone_download_method_list = project_clone_download_method_list.map(
              (item) => {
                return {
                  permission_code: item.permission_code,
                  allowed: formData.method_list.includes(item.permission_code),
                };
              },
            );
          }
        } else {
          formData.project_clone_download_role_list = [];
          formData.project_clone_download_method_list = [];
        }

        delete formData.role_list;
        delete formData.method_list;
        if (this.state.fileList && this.state.fileList.length === 1) {
          formData.avatar_url = this.state.fileList[0].imgUrl;
        } else {
          formData.avatar_url = '';
        }

        // open_clone_download_control 传给后端，如果没修改不传，否则会额外多出日志
        this.deleteCloneDownloadKey(formData);
        this.props.saveGeneral({
          ...formData,
          admin_setting_language: formData.adminSettingLanguage,
        }, (result) => {
          this.setState({ submitting: result });
        });
      } else {
        this.setState({ submitting: false });
      }
    });
  };

  getAvatarName = (url) => {
    return url && url.match(/.*\/(.*)/) ? url.match(/.*\/(.*)/)[1] : url;
  };

  onUploadChange = (files) => {
    if (files && !files.length) {
      this.setState({
        fileList: [],
      });
    }
  };

  uploadError = (f) => {
    let isBeforeUploadError = false;
    if (!['image/png', 'image/jpg', 'image/jpeg', 'image/gif'].includes(f.type)) {
      isBeforeUploadError = true;
      Message.error({
        title: intl.get({
          id: 'code-assets.containers.baseForm.UploadFailedOnlyJpgJpeg',
          defaultMessage: '[上传失败，文件格式仅支持JPG,JPEG,PNG,GIF]',
        }),
      });
    }
    if (f.size >= 1 * 1024 * 1024) {
      isBeforeUploadError = true;
      Message.error({
        title: intl.get({
          id: 'code-assets.containers.baseForm.UploadFailedTheImageSize',
          defaultMessage: '[上传失败，图片大小超过1M]',
        }),
      });
    }
    if (!isBeforeUploadError) {
      Message.warning({
        title:
          f.response && f.response.message
            ? f.response.message
            : intl.get({
              id: 'code-assets.containers.baseForm.UnableToUploadTheAvatar',
              defaultMessage: '头像上传失败',
            }),
      });
    }
    const { fileList } = this.state;
    if (fileList.length === 0) {
      this.changeAvatarUrl(null);
    } else {
      this.changeAvatarUrl(fileList[0]);
    }
  };

  uploadSuccess = (res, file) => {
    if (res && res.response && res.response.code === '0') {
      // Message.success({
      //   title: '头像上传成功',
      // });
      this.changeAvatarUrl(file[0]);
    } else {
      Message.error({
        title: intl.get({
          id: 'code-assets.containers.baseForm.UnableToUploadTheAvatar',
          defaultMessage: '头像上传失败',
        }),
      });
    }
  };

  changeAvatarUrl = (file) => {
    const newfileList = !file
      ? []
      : [
        {
          name: file.name,
          state: file.state,
          size: file.size,
          imgUrl: file.imgUrl || (file.response ? file.response.imgUrl : ''),
          url: file.imgUrl || (file.response ? file.response.imgUrl : ''),
          downloadUrl: file.downloadUrl || (file.response ? file.response.downloadUrl : ''),
        },
      ];

    this.setState({
      fileList: newfileList,
    });
  };

  beforeUpload = (file) => {
    if (!['image/png', 'image/jpg', 'image/jpeg', 'image/gif'].includes(file.type)) {
      return false;
    }
    if (file.size >= 1 * 1024 * 1024) {
      return false;
    }
    return true;
  };

  methodValidator = (rule, value, callback) => {
    if (!value) {
      callback();
      return;
    }
    const role_list = this.field.getValue('role_list');
    if (role_list && role_list.length && !value.length) {
      this.setState({
        method_list: '请勾选允许的方式',
      });
      return;
    } else if (!role_list.length && value.length) {
      this.setState({
        method_list: '请勾选允许的角色',
      });
    } else {
      this.setState({
        method_list: '',
      });
    }
    callback();
  };

  roleValidator = (rule, value, callback) => {
    if (!value) {
      callback();
      return;
    }
    const method_list = this.field.getValue('method_list');
    if (value && value.length && !method_list.length) {
      this.setState({
        method_list: '请勾选允许的方式',
      });
    } else if (!value.length && method_list.length) {
      this.setState({
        method_list: '请勾选允许的角色',
      });
    } else {
      this.setState({
        method_list: '',
      });
    }
    callback();
  };

  cloneLaber = (
    <div>
      克隆下载控制
      {getFeature('project.setting.clone_download_control.need_apply') ?
        <TagForFeature
          type="primary"
          size="small"
          style={{ marginLeft: 8 }}
          tagText="BETA"
        />
        :
        null
      }
    </div>
  );

  disableWebide = (data) => {
    const flag =
      data && data.length > 0 && data.filter((va) => va === 'ssh-clone' || va === 'http-clone');
    return !flag.length;
  };

  render() {
    const { init } = this.field;
    const { name, description, visibilityLevel, clone_download_info, admin_setting_language } =
      this.props;
    const {
      open_clone_download_control,
      enable_clone_download_control,
      clone_download_control_gray,
    } = clone_download_info;
    const { id } = pathResource;
    const { fileList } = this.state;
    // 云上内测

    const is_clone_download_switch_disabled = !clone_download_control_gray || !enable_clone_download_control;

    return (
      <Form {...formItemLayout} field={this.field} labelAlign="top" className="base-form">
        <div className="form-top">
          <div className="project-image-wrapper">
            <Upload.Card
              listType="card"
              action={getPathWithRootPath(`/api/v3/common/image?project_id=${id}&type=avatar${window.FORCE.csrfTokenName
                  ? `&${window.FORCE.csrfTokenName}=${window.FORCE.csrfToken}`
                  : ''
                }`)}
              accept="image/png, image/jpg, image/jpeg, image/gif"
              onChange={this.onUploadChange}
              onSuccess={this.uploadSuccess}
              onError={this.uploadError}
              className="project-image-upload"
              value={fileList}
              beforeUpload={this.beforeUpload}
              limit={1}
            />
          </div>
          <div className="project-name-wrapper">
            <FormItem
              label={intl.get({
                id: 'code-assets.containers.baseForm.CodeLibraryName',
                defaultMessage: '代码库名称',
              })}
              required
            >
              <Input
                placeholder={intl.get({
                  id: 'code-assets.containers.baseForm.EnterACodeLibraryName',
                  defaultMessage: '请输入代码库名称',
                })}
                spellCheck={false}
                maxLength={100}
                hasLimitHint
                {...init('name', {
                  initValue: name,
                  rules: [
                    {
                      required: true,
                      message: intl.get({
                        id: 'code-assets.containers.baseForm.ThisParameterIsRequired',
                        defaultMessage: '该项为必填项',
                      }),
                    },

                    {
                      validator: this.nameValidator,
                    },
                  ],
                })}
              />
            </FormItem>
          </div>
        </div>

        <FormItem
          label={intl.get({
            id: 'code-assets.containers.baseForm.Description',
            defaultMessage: '代码库描述',
          })}
        >
          <Input.TextArea
            placeholder={intl.get({
              id: 'code-assets.containers.baseForm.EnterADescriptionOfThe',
              defaultMessage: '请输入代码库描述',
            })}
            spellCheck={false}
            {...init('description', { initValue: description })}
          />
        </FormItem>
        <FormItem
          required
          label={
            <span>
              {intl.get({
                id: 'code-assets.containers.baseForm.Openness',
                defaultMessage: '公开性',
              })}
            </span>
          }
        >
          <AccessSelect
            {...init('visibility_level', {
              initValue: Number(visibilityLevel),
            })}
            disabled={!this.visibilityLevelCanBeEdited()}
            onChange={this.handleChangeAccess}
            style={{ width: '300px' }}
            pathResourceId={id}
            id="project-setting-visibility-level"
          />
        </FormItem>

        <FormItemSwitch
          title={'编程主语言'}
          description={getFeature('project.setting.coding_language').desc}
        >
          <FormItem label={''}>
            <Select
              {...init('adminSettingLanguage', {
                initValue: admin_setting_language,
              })}
              // onChange={this.handleChangeAccess}
              style={{ width: '300px' }}
              placeholder="暂未选择"
            >
              <Select.Option key="Python" value="Python">
                Python
              </Select.Option>
              <Select.Option key="JavaScript" value="JavaScript">
                JavaScript
              </Select.Option>
              <Select.Option key="Java" value="Java">
                Java
              </Select.Option>
              <Select.Option key="TypeScript" value="TypeScript">
                TypeScript
              </Select.Option>
              <Select.Option key="Golang" value="Golang">
                Golang
              </Select.Option>
              <Select.Option key="Ruby" value="Ruby">
                Ruby
              </Select.Option>
              <Select.Option key="Cpp" value="Cpp">
                C/C++
              </Select.Option>
              <Select.Option key="Rust" value="Rust">
                Rust
              </Select.Option>
              <Select.Option key="default" value="">
                其他
              </Select.Option>
            </Select>
          </FormItem>
        </FormItemSwitch>

        {getFeature('project.setting.clone_download_control') &&
          <FormItemSwitch
            title={this.cloneLaber}
            description={intl.get({
              id: 'code-assets.containers.baseForm.YouCanOnlyCloneAnd',
              defaultMessage:
                '限制代码库的克隆下载操作，开启后仅允许通过勾选的方式进行克隆下载，以增强企业数据安全性。',
            })}
            operation={
              <CloneTooltip
                // 集团内全部开放、云上内测
                disabled={is_clone_download_switch_disabled}
                isAliyunGray={!clone_download_control_gray}
                trigger={
                  <Switch
                    name="switch"
                    disabled={is_clone_download_switch_disabled}
                    checked={this.field.getValue('open_clone_download_control')}
                    {...init('open_clone_download_control', {
                      initValue: open_clone_download_control,
                    })}
                  />
                }
              />
            }
          />}
        {this.field.getValue('open_clone_download_control') ||
          this.field.getValue('open_clone_download_control') ? (
            <Card free className="repo-setting-clone-card">
              <Card.Content>
                {this.field.getValue('open_clone_download_control') && (
                  <FormItem className="" style={{ marginBottom: 4 }}>
                    <div className="repo-setting-clone-detail">
                      <div className="detail-label">
                        {intl.get({
                          id: 'code-assets.containers.baseForm.RolesAllowed',
                          defaultMessage: '允许的角色',
                        })}
                      </div>
                      <CloneTooltip
                        disabled={!enable_clone_download_control}
                        trigger={
                          <Checkbox.Group
                            itemDirection="hoz"
                            {...init('role_list', {
                              initValue: [],
                              rules: [
                                {
                                  validator: this.roleValidator,
                                },
                              ],
                            })}
                            disabled={!enable_clone_download_control}
                          >
                            {roleInfo.map((item) => {
                              return (
                                <Checkbox value={item.value} disabled={item.disabled} key={item.value}>
                                  {item.label}
                                </Checkbox>
                              );
                            })}
                          </Checkbox.Group>
                        }
                      />
                    </div>
                  </FormItem>
                )}

                {this.field.getValue('open_clone_download_control') && (
                  <FormItem className="" style={{ marginBottom: 0 }}>
                    <div className="repo-setting-clone-detail">
                      <div className="detail-label">
                        {intl.get({
                          id: 'code-assets.containers.baseForm.ValidValues',
                          defaultMessage: '允许的方式',
                        })}
                      </div>
                      <CloneTooltip
                        disabled={!enable_clone_download_control}
                        trigger={
                          <Checkbox.Group
                            itemDirection="hoz"
                            {...init('method_list', {
                              initValue: [],
                              rules: [
                                {
                                  validator: this.methodValidator,
                                },
                              ],
                            })}
                            disabled={!enable_clone_download_control}
                          >
                            {cloneWay.map((item) => {
                              return (
                                <Checkbox value={item.value} key={item.value}>
                                  {item.label}
                                </Checkbox>
                              );
                            })}
                          </Checkbox.Group>
                        }
                      />
                    </div>
                    {this.state.method_list ? (
                      <div className="repo-setting-clone-help error">
                        <YunxiaoIcon type="delete-fill" />
                        <span className="next-form-item-help-text">{this.state.method_list}</span>
                      </div>
                    ) : (
                      <div className="repo-setting-clone-help">
                        {intl.get({
                          id: 'code-assets.repositoryPermissions.containers.root.ThisRestrictionDoesNotInclude',
                          defaultMessage: '* 该克隆方式限制范围不包括 Flow 流水线中的使用',
                        })}
                      </div>
                    )}
                    {this.disableWebide(this.field.getValue('method_list')) && (
                      <Message type="warning" style={{ maxWidth: 500, alignItems: 'center' }}>
                        同时限制 SSH 和 HTTPS Clone 时，将禁用 WebIDE
                      </Message>
                    )}
                  </FormItem>
                )}
              </Card.Content>
            </Card>
        ) : null}
        <FormItem className="no-mr-b">
          <Button type="primary" loading={this.state.submitting} onClick={this.saveChanges}>
            {intl.get({ id: 'code-assets.containers.baseForm.Save', defaultMessage: '保存' })}
          </Button>
        </FormItem>
      </Form>
    );
  }
}
